﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.IO;

namespace BDSim
{
    /// <summary>
    /// DataPreview.xaml 的交互逻辑
    /// </summary>
    public partial class DataPreview : UserControl, ILayoutContent
    {
        public DataPreview()
        {
            InitializeComponent();
        }

        #region///字段
        List<string> DataBuffer = new List<string>();

        List<OrbitSimData> OrbitPVList;

        List<ClkSimData> ClkErrList;

        /// <summary>
        /// key（string）代表卫星名称，value代表当前卫星所有星历
        /// </summary>
        public Dictionary<string, List<Ephemeris_16>> SatEph16Dic = new Dictionary<string, List<Ephemeris_16>>();

        List<Ephemeris_16> EphemerisDataList;

        /// <summary>
        /// key（Guid）代表卫星UID，value代表当前卫星名
        /// </summary>
        //public Dictionary<Guid, string> SatelliteFlagDic = new Dictionary<Guid, string>();

        List<UserTrajectoryClass> UserTrackDataList;
        /// <summary>
        /// 观测数据列表
        /// </summary>
        public List<Dictionary<string, List<ObsReceiverOutput>>> ObsDataList = new List<Dictionary<string, List<ObsReceiverOutput>>>();
        /// <summary>
        /// 观测数据产生的三个频点
        /// </summary>
        double[] Freq;

        DataType curType = DataType.OrbitData;

        string LocalObjectName = "";

        ModelType curModelType = ModelType.Satellite;

        string SelectObject;
        #endregion

        #region ///初始化方法
        /// <summary>
        /// 初始化轨道数据
        /// </summary>
        /// <param name="orbitPVList"></param>
        /// <param name="satName"></param>
        public void InitOrbitData(List<OrbitSimData> orbitPVList, string satName)
        {
            stpSelectCoord.Visibility = System.Windows.Visibility.Visible;
            OrbitPVList = orbitPVList;
            LocalObjectName = satName;
            curType = DataType.OrbitData;
            rdbECI.IsChecked = true;
            ConvertData2StringList();
        }

        public void InitClkData(List<ClkSimData> clkDataList, string nodeName)
        {
            ClkErrList = clkDataList;
            LocalObjectName = nodeName;
            curType = DataType.ClkData;
            //curModelType = type;
            ConvertData2StringList();
        }

        /// <summary>
        /// 初始化观测数据报告数据
        /// </summary>
        /// <param name="obsDataList">观测数据</param>
        /// <param name="remoteObjectNameList">远程目标名称列表</param>
        /// <param name="localObjectName">本地目标名称</param>
        /// <param name="freq">测量频率</param>
        public void InitObsData(List<Dictionary<string, List<ObsReceiverOutput>>> obsDataList, List<string> remoteObjectNameList, string localObjectName, double[] freq)
        {
            lblSelectSat.Visibility = System.Windows.Visibility.Visible;
            cbxSelectSat.Visibility = System.Windows.Visibility.Visible;
            btnSaveAll.Visibility = System.Windows.Visibility.Visible;
            ObsDataList = obsDataList;
            LocalObjectName = localObjectName;
            cbxSelectSat.ItemsSource = remoteObjectNameList;
            curType = DataType.ObsData;
            this.Freq = freq;
            ConvertData2StringList();
        }

        public void InitEphemerisData(Dictionary<string, List<Ephemeris_16>> satEph16Dic)
        {
            lblSelectSat.Visibility = System.Windows.Visibility.Visible;
            cbxSelectSat.Visibility = System.Windows.Visibility.Visible;
            btnSaveAll.Visibility = System.Windows.Visibility.Visible;
            cbxSelectSat.ItemsSource = satEph16Dic.Keys;
            SatEph16Dic = satEph16Dic;
            curType = DataType.EphmericData;
            cbxSelectSat.SelectedIndex = 0;
        }

        void SelectEphemerisData(string satName)
        {
            EphemerisDataList = SatEph16Dic[satName];
            LocalObjectName = satName;
            //curType = DataType.EphmericData;
            ConvertData2StringList();
        }

        public void InitUserTrackData(List<UserTrajectoryClass> userTrackDataList, string nodeName)
        {
            curType = DataType.UserTrackData;
            UserTrackDataList = userTrackDataList;
            LocalObjectName = nodeName;
            curModelType = ModelType.UserDevice;
            ConvertData2StringList();
        }

        public void InitPposData(List<object> pposDataList, string nodeName)
        {

        }
        #endregion

        #region ///私有方法
        
        /// <summary>
        /// 根据当前显示数据类型把相应数据转成字符串集合序列
        /// </summary>
        private void ConvertData2StringList()
        {
            switch (curType)
            {
                case DataType.OrbitData:
                    NodePV2StringList();
                    break;
                case DataType.ClkData:
                    Clk2StringList();
                    break;
                case DataType.EphmericData:
                    Ephemeris2StringList();
                    break;
                case DataType.IonData:
                    break;
                case DataType.UserTrackData:
                    TrackDatas2StringList();
                    break;
                case DataType.ObsData:
                    ObsData2StringList(SelectObject);
                    break;
                default:
                    break;
            }
            FillDocument();
        }

        #region///数据集合转成字符数组
        /// <summary>
        /// 轨道数据转成字符集合序列
        /// </summary>
        private void NodePV2StringList()
        {
            DataBuffer.Clear();
            OrbitDataWriter write = new OrbitDataWriter();

            List<NodePosVel> tempPV = new List<NodePosVel>();
            if (rdbECI.IsChecked == true)
            {
                write.InitWriteString(LocalObjectName, CoordinateSystem.J2000);
                for (int i = 0; i < OrbitPVList.Count; i++)
                {
                    tempPV.Add(OrbitPVList[i].SatPV_ECI);
                }
            }
            else if (rdbECF.IsChecked == true)
            {
                write.InitWriteString(LocalObjectName, CoordinateSystem.CGCS2000);
                for (int i = 0; i < OrbitPVList.Count; i++)
                {
                    tempPV.Add(OrbitPVList[i].SatPV_ECF);
                }
            }
            DataBuffer = write.WriteToStringList(tempPV);
        }

        /// <summary>
        /// 钟差集合转成字符数组
        /// </summary>
        private void Clk2StringList()
        {
            DataBuffer.Clear();
            ClockDataWriter write = new ClockDataWriter();
            write.InitClockDataFile(LocalObjectName);
            DataBuffer = write.WriteToStringList(ClkErrList);
        }

        /// <summary>
        /// 星历数据转成字符串
        /// </summary>
        private void Ephemeris2StringList()
        {
            DataBuffer.Clear();
            SixTeen_EphemerisDataWriter write = new SixTeen_EphemerisDataWriter();
            write.InitSixTeen_EphemerisData(LocalObjectName);
            DataBuffer = write.WriteToStringList(EphemerisDataList);
        }

        /// <summary>
        /// 观测数据转成字符串
        /// </summary>
        private void ObsData2StringList(string remoteNodeName)
        {
            DataBuffer.Clear();
            MeasureResultDataWriter obsDataWriter = new MeasureResultDataWriter();
            obsDataWriter.InitCrossLinkDataString(LocalObjectName, 3, Freq[0], Freq[1], Freq[2]);
            if (ObsDataList!= null && ObsDataList.Count != 0)
            {
            }
            else
            {
                MessageBox.Show("未生成观测数据，请打开观测值生成开关（仿真场景右侧属性栏）！");
            }
            DataBuffer = obsDataWriter.WriteString(ObsDataList, remoteNodeName);
        }

        private void TrackDatas2StringList()
        {
            DataBuffer.Clear();
            //把用户轨迹数据转成字符串集合
            TrajectoryDataWriter dataWriter = new TrajectoryDataWriter();
            dataWriter.InitTrajectoryDataWriter(LocalObjectName);
            DataBuffer = dataWriter.WriteToStringList(UserTrackDataList);
        }

        #endregion///数据集合转成字符数组


        /// <summary>
        /// 把字符集合序列填充到文本框中
        /// </summary>
        private void FillDocument()
        {
            textBox1.Visibility = System.Windows.Visibility.Collapsed;
            FlowDocument myFlowDoc = new FlowDocument() { };
            for (int i = 0; i < DataBuffer.Count; i++)
            {
                // Add paragraphs to the FlowDocument.
                myFlowDoc.Blocks.Add(new Paragraph(new Run(DataBuffer[i])) { Margin = new Thickness(0, 3, 0, 3) });
            }
            richTextBox1.Document = myFlowDoc;
            switch (curType)
            {
                case DataType.OrbitData:
                    myFlowDoc.PageWidth = 1000;
                    break;
                case DataType.ClkData:
                    myFlowDoc.PageWidth = 1000;
                    break;
                case DataType.UserTrackData:
                    myFlowDoc.PageWidth = 1200;
                    break;
                case DataType.EphmericData:
                    myFlowDoc.PageWidth = 2300;
                    break;
                case DataType.ObsData:
                    //richTextBox1.Visibility = System.Windows.Visibility.Collapsed;
                    //textBox1.Text = "";
                    //for (int i = 0; i < DataBuffer.Count; i++)
                    //{
                    //    textBox1.Text += DataBuffer[i] + "\r\n";
                    //}

                    myFlowDoc.PageWidth = 2000;
                    break;
                default:
                    break;
            }
        }
        #endregion

        #region 控件触发事件
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            //ConvertData2StringList();
            //FillDocument();
            //if (curType == SaveDataType.OrbitData)
            //{
            //    rdbECI.IsChecked = true;
            //}
        }

        private void rdb_Checked(object sender, RoutedEventArgs e)
        {
            if (curType == DataType.OrbitData && richTextBox1.Document.Blocks.Count != 1)
            //if (curType == SaveDataType.OrbitData && textBox1.Text != null)
            {
                ConvertData2StringList();
                //FillDocument();
            }
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            //  进行当前路径保存
            //string currentDirectory = Directory.GetCurrentDirectory();

            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Export Data(*.txt)|*.txt";
            if (sfd.ShowDialog() == true)
            {
                string filePath = sfd.FileName;
                foreach (var item in DataBuffer)
                {
                    File.AppendAllText(filePath, item + "\r\n");
                }
                MessageBox.Show("保存成功！");
            }

            Directory.SetCurrentDirectory(MainDispatcher.StartPath);
        }

        #endregion

        /// <summary>
        /// 释放资源函数
        /// </summary>
        public void ReleaseData()
        {
            if (OrbitPVList != null)
            {
                OrbitPVList.Clear();
            }

            if (ClkErrList != null)
            {
                ClkErrList.Clear();
            }
            DataBuffer.Clear();
        }

        private void cbxSelectSat_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            switch (curType)
            {
                case DataType.OrbitData:
                    break;
                case DataType.ClkData:
                    break;
                case DataType.EphmericData:
                    SelectObject = (sender as ComboBox).SelectedItem.ToString();
                    SelectEphemerisData(SelectObject);
                    break;
                case DataType.IonData:
                    break;
                case DataType.UserTrackData:
                    break;
                case DataType.ObsData:
                    SelectObject = (sender as ComboBox).SelectedItem.ToString();
                    ConvertData2StringList();
                    break;
                default:
                    break;
            }
        }

        private void btnSaveAll_Click(object sender, RoutedEventArgs e)
        {
            switch (curType)
            {
                case DataType.OrbitData:
                    break;
                case DataType.ClkData:
                    break;
                case DataType.EphmericData:
                    break;
                case DataType.IonData:
                    break;
                case DataType.UserTrackData:
                    break;
                case DataType.ObsData:
                    System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog();
                    fbd.Description = "保存所有观测数据";
                    if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        foreach (var item in cbxSelectSat.Items)
                        {
                            List<string> dataBuffer;
                            MeasureResultDataWriter obsDataWriter = new MeasureResultDataWriter();
                            obsDataWriter.InitCrossLinkDataString(LocalObjectName, 3, Freq[0], Freq[1], Freq[2]);
                            Dictionary<int, string> satNameDic = new Dictionary<int, string>();
                            dataBuffer = obsDataWriter.WriteString(ObsDataList, item.ToString());
                            if (dataBuffer.Count > 10)
                            {
                                string path = fbd.SelectedPath + "\\OBS_" + item.ToString() + ".txt";
                                foreach (var str in dataBuffer)
                                {
                                    File.AppendAllText(path, str + "\r\n");
                                }
                            }
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
